/**
 * @copyright Copyright (c) 2025 
 * CSG Digital Grid Technology (Guangdong) Co., Ltd.
 * @author xxxcsg
 * @brief 鹰眼组件守护进程
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <sys/wait.h>
#include "common.h"

#define DAEMON_PATH "./EagleEyeSMG"
#define WORKING_DIR "/PowerHarmony/SMC/app/EagleEyeSMG/"

// 守护进程化
void daemonize() 
{
    pid_t pid, sid;

    pid = fork();
    if (pid < 0) {
        fprintf(stderr, "Fork failed\n");
        exit(EXIT_FAILURE);
    }
    if (pid > 0) {
        exit(EXIT_SUCCESS);
    }

    // 设置新的会话ID和进程组ID
    sid = setsid();
    if (sid < 0) {
        fprintf(stderr, "Setsid failed\n");
        exit(EXIT_FAILURE);
    }

    // 改变工作目录到根目录，避免影响文件系统卸载
    if ((chdir("/")) < 0) {
        fprintf(stderr, "Chdir failed\n");
        exit(EXIT_FAILURE);
    }

    // 关闭标准输入、输出、错误
    // close(STDIN_FILENO);
    // close(STDOUT_FILENO);
    // close(STDERR_FILENO);
}

// 监控并重启指定程序
void monitor_and_restart() 
{
    pid_t pid, wpid;
    int status;

    signal(SIGCHLD, SIG_IGN); // 忽略子进程终止信号，防止僵尸进程

    while(1) 
    {
        pid = fork();
        if (pid < 0) 
        {
            perror("Fork failed");
            sleep(5); // 等待一段时间后重试
            continue;
        } 
        else if (pid == 0) 
        { // 子进程

            execl( "/PowerHarmony/SMC/app/EagleEyeSMG/EagleEyeSMG","EagleEyeSMG", (char*)NULL);
            perror("Exec failed");
            exit(EXIT_FAILURE);
        }

        // 父进程等待，直到子进程终止或接收到信号
        while((wpid = waitpid(pid, &status, 0)) <= 0 && errno == EINTR);

        if (WIFEXITED(status)) 
        {
            printf("Program %d exited normally, restarting...\n", pid);
        } 
        else if (WIFSIGNALED(status)) 
        {
            printf("Program %d terminated by signal, restarting...\n", pid);
        }

        sleep(5);
    }
}

int main(int argc, char *argv[]) 
{
    if(argc == 2)
    {
        if(!strcmp(argv[1],"-v"))
        {
            printf_func_version(HAWK_EYE_FUNC_DEAMON);
        }
        return 0;
    }
    daemonize(); // 转换为守护进程

    // 改变工作目录到指定路径
    if (chdir(WORKING_DIR) < 0) 
    {
        perror("Change directory failed");
        exit(EXIT_FAILURE);
    }

    printf("Daemon started, monitoring %s...\n", DAEMON_PATH);
    fflush(stdout);

    monitor_and_restart(); // 开始监控并管理目标程序

    return 0; // 实际上不会执行到这里
}